﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ARR.Entities;
using System.Collections.ObjectModel;
using DDF.Entity;
using ARR.UI.StoresService;
using ARR.UI.AttributesService;
using ARR.UI.CountryService;
using ARR.UI.RangeReviewsService;
using ARR.UI.HistoryService;

namespace ARR.UI.Models
{
    public interface IRangeReviewModel : IModelBase
    {
        ObservableCollection<AttributeType> AttributeTypes { get; set; }

        ObservableCollection<Currency> Currencies { get; set; }

        ObservableCollection<CurrencyExchangeRate> CountryCurrencyExchangeRates { get; set; }

        ObservableCollection<CurrencyExchangeRate> CurrencyExchangeRates { get; set; }

        RangeReview CurrentRangeReview { get; set; }

        ObservableCollection<RangeReview> RangeReviews { get; set; }

        ObservableCollection<Store> Stores { get; set; }

        ObservableCollection<RangeReviewStore> RRStores { get; set; }

        List<RangeReviewSetup> RRSetups { get; set; }

        void DeleteRangeReview(RangeReview CurrentRangeRaview);

        void LoadRangeReviews();

        void LoadCurrencies();

        void Save();

        void GetRangeReviewSetups(int rangeReviewId);

        RangeReview GetRangeReview(int rangeReviewId);

        List<History> Histories { get; set; }

        List<History> AllHistories { get; set; }
    }


    public class RangeReviewModel : ModelBase, IRangeReviewModel
    {
        private RangeReview currentRangeReview;


        public RangeReviewModel()
        {
            Stores = new ObservableCollection<Store>();
            RRStores = new ObservableCollection<RangeReviewStore>();
            RangeReviews = new ObservableCollection<RangeReview>();
            Currencies = new ObservableCollection<Currency>();
            CountryCurrencyExchangeRates = new ObservableCollection<CurrencyExchangeRate>();
            CurrencyExchangeRates = new ObservableCollection<CurrencyExchangeRate>();
            AttributeTypes = new ObservableCollection<AttributeType>();

            LoadCurrencies();
            LoadAttributeTypes();
            LoadStores();
            LoadRangeReviews();
            LoadCountryHistories();
        }


        private void LoadCountryHistories()
        {
            HistoryServiceClient service = new HistoryServiceClient();

            try
            {
                AllHistories = service.GetAll(true);
                Histories = AllHistories.Where(x => x.CountryId == WorkspaceData.Instance.Country.Id).ToList();
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }


        public List<History> Histories { get; set; }

        public List<History> AllHistories { get; set; }

        public ObservableCollection<AttributeType> AttributeTypes { get; set; }

        public ObservableCollection<Currency> Currencies { get; set; }

        public ObservableCollection<CurrencyExchangeRate> CountryCurrencyExchangeRates { get; set; }

        public ObservableCollection<CurrencyExchangeRate> CurrencyExchangeRates { get; set; }

        public RangeReview CurrentRangeReview
        {
            get { return currentRangeReview; }
            set
            {
                currentRangeReview = value;
            }
        }

        public ObservableCollection<RangeReview> RangeReviews { get; set; }

        public ObservableCollection<Store> Stores { get; set; }

        public ObservableCollection<RangeReviewStore> RRStores { get; set; }

        public List<RangeReviewSetup> RRSetups { get; set; }

        public void DeleteRangeReview(RangeReview CurrentRangeRaview)
        {

        }


        public void Save()
        {
            //var rangesToSave = RangeReviews.Where(r => r.GetEntityState() != EntityState.Original).ToList();
            //if (rangesToSave.Any())
            //{
            //    using (RangeReviewsServiceClient service = new RangeReviewsServiceClient())
            //    {
            //        service.SaveAll(rangesToSave);
            //        WorkspaceData.Instance.RangeReview = service.GetById(WorkspaceData.Instance.RangeReview.Id, true);
            //    }
            //}

            if (CurrentRangeReview != null && CurrentRangeReview.GetEntityState() != EntityState.Original)
            {
                RangeReviewsServiceClient service = new RangeReviewsServiceClient();

                try
                {
                    service.SaveAll(new List<RangeReview> { CurrentRangeReview });
                    WorkspaceData.Instance.RangeReview = service.GetById(WorkspaceData.Instance.RangeReview.Id, true);
                    service.Close();
                }
                catch
                {
                    service.Abort();
                    throw;
                }
            }

            var ratesToSave = CurrencyExchangeRates.Where(c => c.GetEntityState() != EntityState.Original).ToList();

            CountryServiceClient countryService = new CountryServiceClient();
            try
            {
                countryService.SaveCurrencyExchangeRates(ratesToSave);
                countryService.Close();
            }
            catch
            {
                countryService.Abort();
                throw;
            }
        }

        public void LoadRangeReviews()
        {
            RangeReviewsServiceClient service = new RangeReviewsServiceClient();

            try
            {
                RangeReviews = new ObservableCollection<RangeReview>(service.GetAll(WorkspaceData.Instance.Country.Id, true));
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }

        public void LoadCurrencies()
        {
            CountryServiceClient service = new CountryServiceClient();

            try
            {
                Currencies = new ObservableCollection<Currency>(service.GetAllCurrencies());
                CountryCurrencyExchangeRates = new ObservableCollection<CurrencyExchangeRate>(service.GetCurrencyExchangeRates(WorkspaceData.Instance.Country.Id));
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }

        private void LoadAttributeTypes()
        {
            AttributesServiceClient service = new AttributesServiceClient();

            try
            {
                AttributeTypes = new ObservableCollection<AttributeType>(service.GetAllTypes());
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }

        private void LoadStores()
        {
            StoreServiceClient service = new StoreServiceClient();
            try
            {
                Stores = new ObservableCollection<Store>(service.GetByCountry(WorkspaceData.Instance.Country.Id, false));
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }

        public void GetRangeReviewSetups(int rangeReviewId)
        {
            RangeReviewsServiceClient service = new RangeReviewsServiceClient();

            try
            {
                RRSetups = service.GetRangeReviewSetups(rangeReviewId, 0);
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }
        }

        public RangeReview GetRangeReview(int rangeReviewId)
        {
            RangeReviewsServiceClient service = new RangeReviewsServiceClient();
            RangeReview range = new RangeReview();
            try
            {
                range = service.GetById(rangeReviewId, false);
                service.Close();
            }
            catch
            {
                service.Abort();
                throw;
            }

            return range;
        }
    }


    public class RangeReviewModelMock : MockModelBase, IRangeReviewModel
    {

        public RangeReviewModelMock()
        {
            Stores = new ObservableCollection<Store>();
            RRStores = new ObservableCollection<RangeReviewStore>();
            RangeReviews = new ObservableCollection<RangeReview>();
            Currencies = new ObservableCollection<Currency>();
            CountryCurrencyExchangeRates = new ObservableCollection<CurrencyExchangeRate>();
            CurrencyExchangeRates = new ObservableCollection<CurrencyExchangeRate>();
            AttributeTypes = new ObservableCollection<AttributeType>();

            LoadCurrencies();
            LoadAttributeTypes();
            LoadStores();
            LoadRangeReviews();
        }

        public List<History> Histories { get; set; }

        public List<History> AllHistories { get; set; }

        public ObservableCollection<AttributeType> AttributeTypes { get; set; }

        public ObservableCollection<Currency> Currencies { get; set; }

        public ObservableCollection<CurrencyExchangeRate> CountryCurrencyExchangeRates { get; set; }

        public ObservableCollection<CurrencyExchangeRate> CurrencyExchangeRates { get; set; }

        public RangeReview CurrentRangeReview { get; set; }

        public ObservableCollection<RangeReview> RangeReviews { get; set; }

        public ObservableCollection<Store> Stores { get; set; }

        public ObservableCollection<RangeReviewStore> RRStores { get; set; }

        public void DeleteRangeReview(RangeReview selectedRangeRaview)
        {
            RangeReviews.Remove(selectedRangeRaview);
        }

        public void LoadRangeReviews()
        {
            RangeReviews.Clear();

            RangeReviews.Add(new RangeReview { Id = 1, Title = "Range Review 1", FirstMonth = new DateTime(2010, 05, 01), TotalMonths = 12, TargetCurrency = Currencies[0] });
            RangeReviews.Add(new RangeReview { Id = 2, Title = "Range Review 2", FirstMonth = new DateTime(2010, 09, 01), TotalMonths = 6, TargetCurrency = Currencies[0] });
            RangeReviews.Add(new RangeReview { Id = 3, Title = "Range Review 3", FirstMonth = new DateTime(2010, 12, 01), TotalMonths = 12, TargetCurrency = Currencies[0] });
            RangeReviews.Add(new RangeReview { Id = 4, Title = "Range Review 4", FirstMonth = new DateTime(2011, 05, 01), TotalMonths = 12, TargetCurrency = Currencies[0] });
            RangeReviews.Add(new RangeReview { Id = 5, Title = "Range Review 5", FirstMonth = new DateTime(2011, 09, 01), TotalMonths = 6, TargetCurrency = Currencies[0] });
            RangeReviews.Add(new RangeReview { Id = 6, Title = "Range Review 6", FirstMonth = new DateTime(2011, 12, 01), TotalMonths = 12, TargetCurrency = Currencies[0] });

            foreach (RangeReview rr in RangeReviews)
            {
                rr.Benchmarks = new List<RangeReviewBenchmark>();
                rr.Benchmarks.Add(new RangeReviewBenchmark { Id = 1, RangeReviewSourceId = rr.Id, RangeReviewTargetTitle = RangeReviews[1].Title, RangeReviewTargetId = RangeReviews[1].Id, TargetCurrency = Currencies[1], TargetCurrencyId = Currencies[1].Id });
                rr.Benchmarks.Add(new RangeReviewBenchmark { Id = 2, RangeReviewSourceId = rr.Id, RangeReviewTargetTitle = RangeReviews[2].Title, RangeReviewTargetId = RangeReviews[2].Id, TargetCurrency = Currencies[1], TargetCurrencyId = Currencies[1].Id });
                rr.Benchmarks.Add(new RangeReviewBenchmark { Id = 3, RangeReviewSourceId = rr.Id, RangeReviewTargetTitle = RangeReviews[3].Title, RangeReviewTargetId = RangeReviews[3].Id, TargetCurrency = Currencies[1], TargetCurrencyId = Currencies[1].Id });
                rr.Benchmarks.Add(new RangeReviewBenchmark { Id = 4, RangeReviewSourceId = rr.Id, RangeReviewTargetTitle = RangeReviews[4].Title, RangeReviewTargetId = RangeReviews[4].Id, TargetCurrency = Currencies[1], TargetCurrencyId = Currencies[1].Id });


                rr.RangeReviewStores = new List<RangeReviewStore>();
                rr.RangeReviewStores.Add(new RangeReviewStore { Id = 1, RangeReviewId = rr.Id, Store = Stores[1], IsExcluded = false, IsSameStore = false });
                rr.RangeReviewStores.Add(new RangeReviewStore { Id = 2, RangeReviewId = rr.Id, Store = Stores[2], IsExcluded = false, IsSameStore = false });
                rr.RangeReviewStores.Add(new RangeReviewStore { Id = 3, RangeReviewId = rr.Id, Store = Stores[3], IsExcluded = false, IsSameStore = false });
                rr.RangeReviewStores.Add(new RangeReviewStore { Id = 4, RangeReviewId = rr.Id, Store = Stores[4], IsExcluded = false, IsSameStore = false });

                rr.RangeReviewSetups = new List<RangeReviewSetup>();
                rr.RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 1, Name = "Category 1" }, CategoryId = 1, RangeReviewId = rr.Id, });
                rr.RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 2, Name = "Category 2" }, CategoryId = 2, RangeReviewId = rr.Id, });
                rr.RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 3, Name = "Category 3" }, CategoryId = 3, RangeReviewId = rr.Id, });
                rr.RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 4, Name = "Category 4" }, CategoryId = 4, RangeReviewId = rr.Id, });

                foreach (RangeReviewSetup setup in rr.RangeReviewSetups)
                {
                    List<RangeReviewSetupAttribute> attributes = new List<RangeReviewSetupAttribute>();

                    int indexer = 1;
                    foreach (AttributeType type in AttributeTypes)
                    {
                        attributes.Add(new RangeReviewSetupAttribute { Id = indexer++, AttributeTypeId = type.Id, RangeReviewSetupId = setup.Id, IsChecked = false });
                    }

                    setup.Attributes = attributes.OrderBy(at => at.AttributeTypeId).ToList();
                }

                rr.ChangeState(EntityState.Original);
            }
        }

        public void LoadCurrencies()
        {
            Currencies.Clear();

            Currencies.Add(new Currency { Id = 1, CountryId = 1, CurrencyName = "Argentine Peso", CurrencyISOCode = "ARS" });
            Currencies.Add(new Currency { Id = 2, CountryId = 2, CurrencyName = "US Dollar", CurrencyISOCode = "USD" });
            Currencies.Add(new Currency { Id = 3, CountryId = 3, CurrencyName = "Euro", CurrencyISOCode = "EUR" });
            Currencies.Add(new Currency { Id = 4, CountryId = 4, CurrencyName = "Pound", CurrencyISOCode = "GBP" });
        }

        public void Save()
        {
            if (CurrentRangeReview.Id == 0)
            {
                int newID = 1;

                if (RangeReviews.Any())
                    newID = RangeReviews.Max(st => st.Id) + 1;

                CurrentRangeReview.Id = newID;

                RangeReviews.Add(CurrentRangeReview);
            }
        }


        private void LoadAttributeTypes()
        {
            AttributeTypes.Add(new AttributeType { Id = 1, Name = "ConsumptionType" });
            AttributeTypes.Add(new AttributeType { Id = 2, Name = "SizeSegment" });
            AttributeTypes.Add(new AttributeType { Id = 3, Name = "Flavour" });
        }

        private void LoadStores()
        {
            Stores.Clear();

            Stores.Add(new Store { Id = 1, Code = "ST1", Name = "Store1", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });
            Stores.Add(new Store { Id = 2, Code = "ST2", Name = "Store2", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });
            Stores.Add(new Store { Id = 3, Code = "ST3", Name = "Store3", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });
            Stores.Add(new Store { Id = 4, Code = "ST4", Name = "Store4", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });
            Stores.Add(new Store { Id = 5, Code = "ST5", Name = "Store5", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });
            Stores.Add(new Store { Id = 6, Code = "ST6", Name = "Store6", Address = "Address", City = "City", Region = "Region", Phone = "Phone", Fax = "Fax", Format = "Format", CountryId = 22 });

            foreach (Store st in Stores)
            {
                st.ChangeState(EntityState.Original);
            }
        }

        public List<RangeReviewSetup> GetRangeReviewSetups(int rangeReviewId)
        {
            List<RangeReviewSetup> RangeReviewSetups = new List<RangeReviewSetup>();
            RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 1, Name = "NewCategory 1" }, CategoryId = 1 });
            RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 2, Name = "NewCategory 2" }, CategoryId = 2 });
            RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 3, Name = "NewCategory 3" }, CategoryId = 3 });
            RangeReviewSetups.Add(new RangeReviewSetup { Category = new Category { Id = 4, Name = "NewCategory 4" }, CategoryId = 4 });

            foreach (RangeReviewSetup setup in RangeReviewSetups)
            {
                List<RangeReviewSetupAttribute> attributes = new List<RangeReviewSetupAttribute>();

                int indexer = 1;
                foreach (AttributeType type in AttributeTypes)
                {
                    attributes.Add(new RangeReviewSetupAttribute { Id = indexer++, AttributeTypeId = type.Id, RangeReviewSetupId = setup.Id, IsChecked = false });
                }

                setup.Attributes = attributes.OrderBy(at => at.AttributeTypeId).ToList();
            }

            return RangeReviewSetups;
        }

        void IRangeReviewModel.GetRangeReviewSetups(int rangeReviewId)
        {

        }


        public List<RangeReviewSetup> RRSetups
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }


        public RangeReview GetRangeReview(int rangeReviewId)
        {
            throw new NotImplementedException();
        }
    }
}
